from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from typing import List, Optional
from app.models.database.models import ServiceConfig, HealthCheck
from app.models.schemas.service import (
    ServiceConfigCreate, ServiceConfigUpdate, ServiceConfigResponse,
    ServiceStatus, SwitchRequest, SwitchResponse, HealthCheckResponse,
    SwitchLogResponse
)
from app.core.config.database import get_db
from app.services.switching.switch_manager import switch_manager
from app.services.monitoring.failure_detector import failure_detector
from app.services.monitoring.scheduler import scheduler
import logging

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/services", tags=["services"])


@router.post("/", response_model=ServiceConfigResponse)
async def create_service(
        service: ServiceConfigCreate,
        db: Session = Depends(get_db)
):
    """创建新的服务配置"""

    # 检查服务名称是否已存在
    existing = db.query(ServiceConfig).filter(ServiceConfig.name == service.name).first()
    if existing:
        raise HTTPException(status_code=400, detail="Service name already exists")

    db_service = ServiceConfig(**service.dict())
    db.add(db_service)
    db.commit()
    db.refresh(db_service)

    # 更新监控计划
    await scheduler.update_service_schedule(db_service.id)

    logger.info(f"Created new service: {service.name}")
    return db_service


@router.get("/", response_model=List[ServiceConfigResponse])
async def list_services(
        skip: int = Query(0, ge=0),
        limit: int = Query(100, ge=1, le=1000),
        is_active: Optional[bool] = None,
        db: Session = Depends(get_db)
):
    """获取服务列表"""

    query = db.query(ServiceConfig)

    if is_active is not None:
        query = query.filter(ServiceConfig.is_active == is_active)

    services = query.offset(skip).limit(limit).all()
    return services


@router.get("/{service_id}", response_model=ServiceConfigResponse)
async def get_service(
        service_id: int,
        db: Session = Depends(get_db)
):
    """获取单个服务详情"""

    service = db.query(ServiceConfig).filter(ServiceConfig.id == service_id).first()
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")

    return service


@router.put("/{service_id}", response_model=ServiceConfigResponse)
async def update_service(
        service_id: int,
        service_update: ServiceConfigUpdate,
        db: Session = Depends(get_db)
):
    """更新服务配置"""

    service = db.query(ServiceConfig).filter(ServiceConfig.id == service_id).first()
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")

    # 更新字段
    update_data = service_update.model_dump(exclude_unset=True)
    for field, value in update_data.items():
        setattr(service, field, value)

    db.commit()
    db.refresh(service)

    # 通过 scheduler 实例调用 update_service_schedule 方法
    await scheduler.update_service_schedule(service_id)

    logger.info(f"Updated service: {service.name}")
    return service


@router.delete("/{service_id}")
async def delete_service(
        service_id: int,
        db: Session = Depends(get_db)
):
    """删除服务"""

    service = db.query(ServiceConfig).filter(ServiceConfig.id == service_id).first()
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")

    db.delete(service)
    db.commit()

    logger.info(f"Deleted service: {service.name}")
    return {"message": "Service deleted successfully"}


@router.get("/{service_id}/status", response_model=ServiceStatus)
async def get_service_status(
        service_id: int,
        db: Session = Depends(get_db)
):
    """获取服务状态"""

    service = db.query(ServiceConfig).filter(ServiceConfig.id == service_id).first()
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")

    return switch_manager.get_current_status(service_id, db)


@router.post("/{service_id}/health-check", response_model=HealthCheckResponse)
async def trigger_health_check(
        service_id: int,
        force: bool = Query(False, description="强制检查"),
        db: Session = Depends(get_db)
):
    """触发健康检查"""

    from app.services.health.health_checker import health_checker

    service = db.query(ServiceConfig).filter(ServiceConfig.id == service_id).first()
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")

    result = await health_checker.check_service_health(service, db)

    # 返回最新的健康检查记录
    latest_check = db.query(HealthCheck) \
        .filter(HealthCheck.service_id == service_id) \
        .order_by(HealthCheck.checked_at.desc()) \
        .first()

    return latest_check


@router.post("/{service_id}/switch", response_model=SwitchResponse)
async def switch_service(
        service_id: int,
        switch_request: SwitchRequest,
        db: Session = Depends(get_db)
):
    """手动切换服务"""

    service = db.query(ServiceConfig).filter(ServiceConfig.id == service_id).first()
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")

    result = await switch_manager.perform_switch(
        service_id=service_id,
        target_status=switch_request.target_status,
        switch_type="manual",
        reason=switch_request.reason,
        operator=switch_request.operator,
        db=db
    )

    return SwitchResponse(**result)


@router.get("/{service_id}/switch-history", response_model=List[SwitchLogResponse])
async def get_switch_history(
        service_id: int,
        limit: int = Query(50, ge=1, le=1000),
        db: Session = Depends(get_db)
):
    """获取切换历史"""

    service = db.query(ServiceConfig).filter(ServiceConfig.id == service_id).first()
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")

    history = switch_manager.get_switch_history(service_id, limit, db)
    return history


@router.get("/{service_id}/health-history", response_model=List[HealthCheckResponse])
async def get_health_history(
        service_id: int,
        limit: int = Query(100, ge=1, le=1000),
        hours: int = Query(24, ge=1, le=168),
        db: Session = Depends(get_db)
):
    """获取健康检查历史"""

    from datetime import datetime, timedelta

    service = db.query(ServiceConfig).filter(ServiceConfig.id == service_id).first()
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")

    start_time = datetime.utcnow() - timedelta(hours=hours)

    checks = db.query(HealthCheck) \
        .filter(
        HealthCheck.service_id == service_id,
        HealthCheck.checked_at >= start_time
    ) \
        .order_by(HealthCheck.checked_at.desc()) \
        .limit(limit) \
        .all()

    return checks


@router.get("/{service_id}/uptime")
async def get_service_uptime(
        service_id: int,
        days: int = Query(7, ge=1, le=30),
        db: Session = Depends(get_db)
):
    """获取服务可用性统计"""

    service = db.query(ServiceConfig).filter(ServiceConfig.id == service_id).first()
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")

    uptime_stats = failure_detector.get_service_uptime(service_id, days, db)
    return uptime_stats